<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
</head>
<body>
	<script>
		"use strict"
		// 1.对象的属性特征
		console.log("------一、对象属性特征的深入研究-------------")
		let obj ={
			name:"张三",
			age:11,
			color:"red"
		};


		console.dir(Object)
		//1.1 查看对象属性特征
		console.log("1.1 查看对象的所有属性特征：",Object.getOwnPropertyDescriptors(obj));


		//1.2 修改对象属性特征
		Object.defineProperty(obj,"name",{
			configurable: true,
			enumerable: false,
			value: "张三1111",
			writable: false,
		});

		// obj.name="zhangsan222" //无效操作
		// Object.defineProperty(obj,"name",{ //无效操作
		// 	configurable: false,
		// 	enumerable: false,
		// 	value: "张三333",
		// 	writable: false,
		// });
		

		console.log("1.2 修改对象的属性特征：",obj.name);


		Object.defineProperties(obj,{
			name:{
				configurable: true,
				enumerable:true,
				value: "张三222",
				writable: true,
			},
			age:{
				configurable: true,
				enumerable: true,
				value: 22,
				writable: true,
			}
		})
		console.log("1.2 批量修改对象的属性特征：",obj.name+"=="+obj.age);


		//1.3 禁止添加对象属性的接口（不能添加，但是可以修改和删除）
		Object.preventExtensions(obj);
		// obj.sex="男";//无效操作
		// obj.name ="zhansan333";//有效操作
		// delete obj.color //有效操作
		console.log("1.3 禁止添加对象属性的接口：",
					obj,"----",
					Object.keys(obj),"----",
					Object.values(obj),"----",
					Object.getOwnPropertyNames(obj),
					Object.isExtensible(obj)
					); 



		// 1.4 封闭对象的接口(不能添加也不能删除，但是可以修改)
		Object.seal(obj);
		obj.name = "zhansan 444";
		// obj.sex ="男444";//无效操作
		// delete obj.color//无效操作
		console.log("1.4 封闭对象的接口：",obj,Object.isSealed(obj));


		// 1.5 冻结对象的api接口(无法对该对象进行任何操作)
		Object.freeze(obj);
		// obj.name="zhansan 55";//无效操作
		// obj.sex="男55";//无效操作
		// delete obj.color;//无效操作
		console.log("1.5 冻结对象的接口：",obj,Object.isFrozen(obj));



		// 2.对象的访问器
		console.log("-------二、对象访问器的深入研究-----------");
		let person ={
			name:'lisi',
			like:"red",
			age:77,
			hobby:{width:"18cm"},
			run(run="running"){
				console.log(this.name+"今年"+this.age+"喜欢"+run)
			},
			work:function(work="teacher"){
				console.log(this.name+"的工作是"+work)
			},

			// 定义访问器
			// 2.1修改普通属性的 访问器
			get name1(){
				return this.name+"!"
			},
			set name1(value){
				this.name = value+"!";
				return true
			},
			// 2.2 修改私有属性的访问器
			get width(){
				return this.hobby.width+"!"
			},
			set width(value){
				this.hobby.width=value+"!";
				return true
			},
			// 2.3 get访问器伪造属性（vue计算属性的原理）
			get counterfeit(){
				return this.hobby.width+"@我是伪造的属性哈"
			},
			// 2.4 set访问器批量设置属性（解构原理）
			set myvalues(value){
				 [this.name,this.age]=value.split(",")
				 return true
			},
			// 2.5 访问器与本地存储技术结合
			get token(){
				return localStorage.getItem("token");
			},
			set token(value){
				localStorage.setItem("token",value);
				return true
			}
			
		}


		// person.run("code");
		// person.work();
		// console.log(person.hobby.width)

		// 2.1 访问器修改普通属性（优先级高于点语法）
		person.name1="lisi111";
		console.log(" 2.1 访问器修改普通属性:",person.name1);
		// 2.2 修改私有属性的访问器
		person.width = "25cm";
		console.log(" 2.2 访问器修改私有属性:",person.width);
		// 2.3 访问器伪造属性（vue计算属性的原理）
		console.log(" 2.3 访问器伪造属性:",person.counterfeit);
		// 2.4 set访问器批量设置属性（解构原理）
		person.myvalues="lisi4444,67";
		console.log(" 2.4 set访问器批量设置属性:",person);
		// 2.5 访问器与本地存储技术结合
		person.token = "token999999999999";
		console.log("2.5 访问器与本地存储技术结合: ",person.token);





		// 3.proxy代理
		console.log("-------三、proxy代理的深入研究-----------");

		// 3.1 proxy代理对象
		var obj3={
			name:"wangwu",
			age:34,
			doing(done="swiming"){
				console.log(this.name+"正在"+done)
			}
		}
		obj3.doing()
		let proxy = new Proxy(obj3,{
			get(obj,property){
				return obj[property]
			},
			set(obj,property,value){
				obj[property] = value;
				return true
			}
		})
		proxy.color ="green"
		console.log("3.1 proxy代理对象:", proxy.name,proxy,obj3);



		// 3.2 代理函数
		function jisuan(num1,num2,fuhao){
			var res =0;
			switch (fuhao){
				case '+': res = Number(num1) + Number(num2)
					break;
				case "-":res = Number(num1) - Number(num2)
					break;
				case "*": res = Number(num1) * Number(num2)
					break;
				case "/": res = Number(num1) / Number(num2)
					break;
				default: res = "符号错误"
			}
			return console.log(res)
				
		}

		let proxyfn = new Proxy(jisuan,{
			apply(fn,obj,args){
				fn.apply({},args);
				// return true
			}
		})
		console.log("3.2 proxy代理函数:",proxyfn(2,3,"+"));





		// 3.3 proxy代理数组 
		var arr =["小李","小明"]
		let proxyArr =new Proxy(arr,{
			get(arr,index){
				return arr[index]
			},
			set(arr,index,value){
				arr[index] = value;
				return true
			}
		})
		proxyArr[1]="xiaoming"
		console.log("3.3 proxy代理数组:",proxyArr[1]);
		














	</script>
	
</body>
</html>